package com.saianfu.flowable.demo.controller

import com.saianfu.flowable.demo.common.impl.InstanceHandler
import com.saianfu.flowable.demo.common.impl.ProcessHandler
import com.saianfu.flowable.demo.controller.result.ResponseData
import io.swagger.annotations.Api
import io.swagger.annotations.ApiImplicitParam
import io.swagger.annotations.ApiImplicitParams
import io.swagger.annotations.ApiOperation
import org.flowable.engine.repository.Deployment
import org.slf4j.LoggerFactory
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestMethod
import org.springframework.web.bind.annotation.ResponseBody
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.MultipartFile
import java.io.IOException
import java.io.InputStream

/**
 *
 *
 * 部署流程定义
 *
 *
 */
@RestController
@RequestMapping("api/flow/process")
@Api(value = "Process", tags = ["流程模板"])
class ProcessController {
    @Autowired
    lateinit var processHandler: ProcessHandler

    /**
     * 部署流程定义
     */
    @RequestMapping(value = ["/deploy/repeat"], method = [RequestMethod.GET])
    @ResponseBody
    @ApiOperation(value = "部署流程定义(每次都部署）", produces = "application/json")
    @ApiImplicitParams(ApiImplicitParam(name = "name", value = "流程定义名称（即：模板ID）", required = true, dataType = "String"))
    fun deployRepeat(bpmnName: String, deploymentName: String, categoryName: String?): ResponseData<Deployment?> {
        logger.info("部署流程定义start")
        val deploy = processHandler.deploy("processes/$bpmnName.bpmn20.xml", deploymentName, categoryName)
        logger.info("部署流程定义end--{}:{}", deploy.id, deploy.name)
        return ResponseData.success(deploy)
    }

    /**
     * 部署流程定义
     */
    @RequestMapping(value = ["/deploy/noRepeat"], method = [RequestMethod.GET])
    @ResponseBody
    @ApiOperation(value = "部署流程定义(仅首次部署）", produces = "application/json")
    @ApiImplicitParams(ApiImplicitParam(name = "name", value = "流程定义名称（即：模板ID）", required = true, dataType = "String"))
    fun deployNoRepeat(bpmnName: String, deploymentName: String, categoryName: String?): ResponseData<*> {
        val exist = processHandler.exist(deploymentName)
        if (!exist) {
            logger.info("部署流程定义start")
            val deploy = processHandler.deploy("processes/$bpmnName.bpmn20.xml", null, deploymentName, categoryName)
            logger.info("部署流程定义end--{}:{}", deploy.id, deploy.name)
            return ResponseData.success(deploy)
        }
        return ResponseData.success()
    }

    /**
     * 部署流程定义
     */
    @ResponseBody
    @ApiOperation(value = "部署流程模板文件", notes = "模板与工作流微服务解耦，模板文件可来自网络中某个位置，也可以来自业务项目")
    @ApiImplicitParams(ApiImplicitParam(name = "name", value = "模板名称（模板ID）", required = true, dataType = "String"), ApiImplicitParam(name = "category", value = "模板类别", dataType = "String"), ApiImplicitParam(name = "file", value = "模板文件", required = true, dataType = "__file"))
    @RequestMapping(value = ["/deploy/file"], method = [RequestMethod.POST], headers = ["content-type=multipart/form-data"])
    fun deployByInputStream(deploymentName: String, categoryName: String, file: MultipartFile): ResponseData<Deployment?> {
        var `in`: InputStream? = null
        var deploy: Deployment? = null
        try {
            val exist = processHandler!!.exist(deploymentName)
            if (!exist) {
                `in` = file.inputStream
                deploy = processHandler.deploy(deploymentName, categoryName, `in`)
            }
        } catch (e: Exception) {
            logger.error("部署流程模板失败:", e)
        } finally {
            try {
                `in`?.close()
            } catch (e: IOException) {
                logger.error("关闭输入流出错", e)
            }
        }
        return ResponseData.success(deploy)
    }

    companion object {
        protected var logger = LoggerFactory.getLogger(InstanceHandler::class.java)
    }
}